package math;

import static math.ExpressionBuilder.cos;
import static math.ExpressionBuilder.neg;
import static math.ExpressionBuilder.mult;

public class Cos implements ArithmeticExpression {

  private ArithmeticExpression arg;

  private Cos(ArithmeticExpression arg) {
    this.arg = arg;
  }

  public static Cos createCos(ArithmeticExpression arg) {
    return new Cos(arg);
  }

  @Override
  public boolean isOne() {
    return arg.isZero();
  }

  @Override
  public boolean isZero() {
    return false;
  }

  @Override
  public ArithmeticExpression derivate(Variable var) {
    return neg(mult(arg.derivate(var), cos(arg)));
  }
  
  @Override
  public int countMembers() {
    return 1 + arg.countMembers();
  }

  @Override
  public int getPriority() {
    return 2;
  }

  @Override
  public ArithmeticExpression simplify() {
    return this;
  }

  @Override
  public String toString() {
    return "cos(" + arg.toString() + ")";
  }

  @Override
  public boolean matches(Expression expr) {
    if (expr instanceof Cos) {
      Cos eCos = (Cos) expr;
      return arg.matches(eCos.getArgument());
    } else
      return false;
  }

  public ArithmeticExpression getArgument() {
    return arg;
  }
  
  @Override
  public boolean equals(Object obj) {
    if (obj instanceof Cos) {
      Cos cos2 = (Cos) obj;
      return cos2.arg.equals(arg);
    } else
      return false;
  }

  @Override
  public int hashCode() {
    return arg.hashCode() / PI.PI.hashCode();
  }
  
  @Override
  public <R> R accept(ExpressionVisitor<R> visitor) {
    return visitor.visitCos(this);
  }
}